package org.linlinjava.litemall.wx.web;

import static org.linlinjava.litemall.wx.util.WxResponseCode.ADMIN_INVALID_NAME;
import static org.linlinjava.litemall.wx.util.WxResponseCode.ADMIN_INVALID_PASSWORD;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_CAPTCHA_FREQUENCY;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_CAPTCHA_UNMATCH;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_CAPTCHA_UNSUPPORT;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_INVALID_ACCOUNT;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_INVALID_MOBILE;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MERCHANT_CA_COMPANY;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MERCHANT_CA_CONTACT;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MERCHANT_CA_HERB;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MERCHANT_CA_QUALIFICATION;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MERCHANT_CA_USER;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MOBILE_REGISTERED;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_MOBILE_UNREGISTERED;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_NAME_REGISTERED;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_OPENID_BINDED;
import static org.linlinjava.litemall.wx.util.WxResponseCode.AUTH_OPENID_UNACCESS;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.notify.NotifyType;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.IpUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.RegexUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.constant.DBConmonConstant;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.domain.LitemallUserApprove;
import org.linlinjava.litemall.db.domain.LitemallUserHerbApproveItem;
import org.linlinjava.litemall.db.service.CouponAssignService;
import org.linlinjava.litemall.db.service.LitemallUserApproveService;
import org.linlinjava.litemall.db.service.LitemallUserHerbApproveItemService;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.dto.UserInfo;
import org.linlinjava.litemall.wx.dto.WxLoginInfo;
import org.linlinjava.litemall.wx.service.CaptchaCodeManager;
import org.linlinjava.litemall.wx.service.TokenHelper;
import org.linlinjava.litemall.wx.service.UserTokenManager;
import org.linlinjava.litemall.wx.service.WxQualificationsService;
import org.linlinjava.litemall.wx.vo.QualificationsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;

/**
 * 鉴权服务
 */
@RestController
@RequestMapping("/wx/auth")
@Validated
public class WxAuthController {
	private final Log logger = LogFactory.getLog(WxAuthController.class);

	@Autowired
	private LitemallUserService userService;

	@Autowired
	private LitemallUserApproveService userApproveService;

	@Autowired
	private LitemallUserHerbApproveItemService userHerbApproveItemService;

	@Autowired
	private WxQualificationsService wxQualificationsService;

//	@Autowired
//	private UserInfoService userInfoService;
    @Autowired
    private TokenHelper tokenHelper;

	@Autowired
	private WxMaService wxService;

	@Autowired
	private NotifyService notifyService;

	@Autowired
	private CouponAssignService couponAssignService;

	/**
	 * 账号登录
	 *
	 * @param body    请求内容，{ username: xxx, password: xxx }
	 * @param request 请求对象
	 * @return 登录结果
	 */
	@PostMapping("login")
	public Object login(@RequestBody String body, HttpServletRequest request) {
		String username = JacksonUtil.parseString(body, "username");
		String password = JacksonUtil.parseString(body, "password");
		if (username == null || password == null) {
			return ResponseUtil.badArgument();
		}

		List<LitemallUser> userList = userService.queryByUsername(username);
		LitemallUser user = null;
		if (userList.size() > 1) {
			return ResponseUtil.serious();
		} else if (userList.size() == 0) {
			return ResponseUtil.fail(AUTH_INVALID_ACCOUNT, "账号不存在");
		} else {
			user = userList.get(0);
		}

		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		if (!encoder.matches(password, user.getPassword())) {
			return ResponseUtil.fail(AUTH_INVALID_ACCOUNT, "账号密码不对");
		}

		// 更新登录情况
		user.setLastLoginTime(LocalDateTime.now());
		user.setLastLoginIp(IpUtil.getIpAddr(request));
		if (userService.updateById(user) == 0) {
			return ResponseUtil.updatedDataFailed();
		}

		// userInfo
		UserInfo userInfo = new UserInfo();
		userInfo.setNickName(username);
		userInfo.setAvatarUrl(user.getAvatar());

		// token
		String token = UserTokenManager.generateToken(user.getId());

		Map<Object, Object> result = new HashMap<Object, Object>();
		result.put("token", token);
		result.put("userInfo", userInfo);
		return ResponseUtil.ok(result);
	}

	/**
	 * 微信登录
	 *
	 * @param wxLoginInfo 请求内容，{ code: xxx, userInfo: xxx }
	 * @param request     请求对象
	 * @return 登录结果
	 */
	@PostMapping("login_by_weixin")
	public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {
		String code = wxLoginInfo.getCode();
		UserInfo userInfo = wxLoginInfo.getUserInfo();
		if (code == null || userInfo == null) {
			return ResponseUtil.badArgument();
		}

		String sessionKey = null;
		String openId = null;
		try {
			WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
			sessionKey = result.getSessionKey();
			openId = result.getOpenid();
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (sessionKey == null || openId == null) {
			return ResponseUtil.fail();
		}

		Map<String, Object> shopInfo = null;
		LitemallUser user = userService.queryByOid(openId);
		if (user == null) {
			user = new LitemallUser();
			user.setUsername(openId);
			user.setPassword(openId);
			user.setWeixinOpenid(openId);
			user.setAvatar(userInfo.getAvatarUrl());
			user.setNickname(userInfo.getNickName());
			user.setGender(userInfo.getGender());
			user.setUserLevel((byte) 0);
			user.setStatus((byte) 0);
			user.setLastLoginTime(LocalDateTime.now());
			user.setLastLoginIp(IpUtil.getIpAddr(request));
			user.setSessionKey(sessionKey);

			user.setMainUser((byte) 1);// 默认设置为主账号
			user.setAuthStatus((byte) 0);// 默认状态：未审核

			userService.add(user);

		} else {
			shopInfo = wxQualificationsService.getShopAuthInfo(user.getId());

			user.setLastLoginTime(LocalDateTime.now());
			user.setLastLoginIp(IpUtil.getIpAddr(request));
			user.setSessionKey(sessionKey);
			if (userService.updateById(user) == 0) {
				return ResponseUtil.updatedDataFailed();
			}
		}

		// token
		String token = UserTokenManager.generateToken(user.getId());
		
		tokenHelper.saveToken(user.getId(), token);

		Map<Object, Object> result = new HashMap<Object, Object>();
		result.put("token", token);
		result.put("userInfo", userInfo);
		result.put("shopInfo", shopInfo);
		result.put("user", user);// TODO 对返回项做限制
		return ResponseUtil.ok(result);
	}

	/**
	 * 请求注册验证码
	 *
	 * TODO 这里需要一定机制防止短信验证码被滥用
	 *
	 * @param body 手机号码 { mobile }
	 * @return
	 */
	@PostMapping("regCaptcha")
	public Object registerCaptcha(@RequestBody String body) {
		String phoneNumber = JacksonUtil.parseString(body, "mobile");
		if (StringUtils.isEmpty(phoneNumber)) {
			return ResponseUtil.badArgument();
		}
		if (!RegexUtil.isMobileSimple(phoneNumber)) {
			return ResponseUtil.badArgumentValue();
		}

		if (!notifyService.isSmsEnable()) {
			return ResponseUtil.fail(AUTH_CAPTCHA_UNSUPPORT, "小程序后台验证码服务不支持");
		}
		String code = CharUtil.getRandomNum(6);
		boolean successful = CaptchaCodeManager.addToCache(phoneNumber, code);
		if (!successful) {
			return ResponseUtil.fail(AUTH_CAPTCHA_FREQUENCY, "验证码未超时1分钟，不能发送");
		}
		notifyService.notifySmsTemplate(phoneNumber, NotifyType.CAPTCHA, new String[] { code });

		return ResponseUtil.ok();
	}

	/**
	 * 账号注册
	 *
	 * @param body    请求内容 { username: xxx, password: xxx, mobile: xxx code: xxx }
	 *                其中code是手机验证码，目前还不支持手机短信验证码
	 * @param request 请求对象
	 * @return 登录结果 成功则 { errno: 0, errmsg: '成功', data: { token: xxx, tokenExpire:
	 *         xxx, userInfo: xxx } } 失败则 { errno: XXX, errmsg: XXX }
	 */
	@PostMapping("register")
	public Object register(@RequestBody String body, HttpServletRequest request) {
		String username = JacksonUtil.parseString(body, "username");
		String password = JacksonUtil.parseString(body, "password");
		String mobile = JacksonUtil.parseString(body, "mobile");
		String code = JacksonUtil.parseString(body, "code");
		// 如果是小程序注册，则必须非空
		// 其他情况，可以为空
		String wxCode = JacksonUtil.parseString(body, "wxCode");

		if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || StringUtils.isEmpty(mobile)
				|| StringUtils.isEmpty(code)) {
			return ResponseUtil.badArgument();
		}

		List<LitemallUser> userList = userService.queryByUsername(username);
		if (userList.size() > 0) {
			return ResponseUtil.fail(AUTH_NAME_REGISTERED, "用户名已注册");
		}

		userList = userService.queryByMobile(mobile);
		if (userList.size() > 0) {
			return ResponseUtil.fail(AUTH_MOBILE_REGISTERED, "手机号已注册");
		}
		if (!RegexUtil.isMobileSimple(mobile)) {
			return ResponseUtil.fail(AUTH_INVALID_MOBILE, "手机号格式不正确");
		}
		// 判断验证码是否正确
		String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
		if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code)) {
			return ResponseUtil.fail(AUTH_CAPTCHA_UNMATCH, "验证码错误");
		}

		String openId = "";
		// 非空，则是小程序注册
		// 继续验证openid
		if (!StringUtils.isEmpty(wxCode)) {
			try {
				WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(wxCode);
				openId = result.getOpenid();
			} catch (Exception e) {
				e.printStackTrace();
				return ResponseUtil.fail(AUTH_OPENID_UNACCESS, "openid 获取失败");
			}
			userList = userService.queryByOpenid(openId);
			if (userList.size() > 1) {
				return ResponseUtil.serious();
			}
			if (userList.size() == 1) {
				LitemallUser checkUser = userList.get(0);
				String checkUsername = checkUser.getUsername();
				String checkPassword = checkUser.getPassword();
				if (!checkUsername.equals(openId) || !checkPassword.equals(openId)) {
					return ResponseUtil.fail(AUTH_OPENID_BINDED, "openid已绑定账号");
				}
			}
		}

		LitemallUser user = null;
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		String encodedPassword = encoder.encode(password);
		user = new LitemallUser();
		user.setUsername(username);
		user.setPassword(encodedPassword);
		user.setMobile(mobile);
		user.setWeixinOpenid(openId);
		user.setAvatar(
				"https://yanxuan.nosdn.127.net/80841d741d7fa3073e0ae27bf487339f.jpg?imageView&quality=90&thumbnail=64x64");
		user.setNickname(username);
		user.setGender((byte) 0);
		user.setUserLevel((byte) 0);
		user.setStatus((byte) 0);
		user.setLastLoginTime(LocalDateTime.now());
		user.setLastLoginIp(IpUtil.getIpAddr(request));
		userService.add(user);

		// 给新用户发送注册优惠券
		couponAssignService.assignForRegister(user.getId());

		// userInfo
		UserInfo userInfo = new UserInfo();
		userInfo.setNickName(username);
		userInfo.setAvatarUrl(user.getAvatar());

		// token
		String token = UserTokenManager.generateToken(user.getId());

		Map<Object, Object> result = new HashMap<Object, Object>();
		result.put("token", token);
		result.put("userInfo", userInfo);
		return ResponseUtil.ok(result);
	}

	/**
	 * 请求验证码
	 *
	 * TODO 这里需要一定机制防止短信验证码被滥用
	 *
	 * @param body 手机号码 { mobile: xxx, type: xxx }
	 * @return
	 */
	@PostMapping("captcha")
	public Object captcha(@LoginUser Integer userId, @RequestBody String body) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		String phoneNumber = JacksonUtil.parseString(body, "mobile");
		String captchaType = JacksonUtil.parseString(body, "type");
		if (StringUtils.isEmpty(phoneNumber)) {
			return ResponseUtil.badArgument();
		}
		if (!RegexUtil.isMobileSimple(phoneNumber)) {
			return ResponseUtil.badArgumentValue();
		}
		if (StringUtils.isEmpty(captchaType)) {
			return ResponseUtil.badArgument();
		}

		if (!notifyService.isSmsEnable()) {
			return ResponseUtil.fail(AUTH_CAPTCHA_UNSUPPORT, "小程序后台验证码服务不支持");
		}
		String code = CharUtil.getRandomNum(6);
		boolean successful = CaptchaCodeManager.addToCache(phoneNumber, code);
		if (!successful) {
			return ResponseUtil.fail(AUTH_CAPTCHA_FREQUENCY, "验证码未超时1分钟，不能发送");
		}
		notifyService.notifySmsTemplate(phoneNumber, NotifyType.CAPTCHA, new String[] { code });

		return ResponseUtil.ok();
	}

	/**
	 * 账号密码重置
	 *
	 * @param body    请求内容 { password: xxx, mobile: xxx code: xxx }
	 *                其中code是手机验证码，目前还不支持手机短信验证码
	 * @param request 请求对象
	 * @return 登录结果 成功则 { errno: 0, errmsg: '成功' } 失败则 { errno: XXX, errmsg: XXX }
	 */
	@PostMapping("reset")
	public Object reset(@RequestBody String body, HttpServletRequest request) {
		String password = JacksonUtil.parseString(body, "password");
		String mobile = JacksonUtil.parseString(body, "mobile");
		String code = JacksonUtil.parseString(body, "code");

		if (mobile == null || code == null || password == null) {
			return ResponseUtil.badArgument();
		}

		// 判断验证码是否正确
		String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
		if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code))
			return ResponseUtil.fail(AUTH_CAPTCHA_UNMATCH, "验证码错误");

		List<LitemallUser> userList = userService.queryByMobile(mobile);
		LitemallUser user = null;
		if (userList.size() > 1) {
			return ResponseUtil.serious();
		} else if (userList.size() == 0) {
			return ResponseUtil.fail(AUTH_MOBILE_UNREGISTERED, "手机号未注册");
		} else {
			user = userList.get(0);
		}

		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		String encodedPassword = encoder.encode(password);
		user.setPassword(encodedPassword);

		if (userService.updateById(user) == 0) {
			return ResponseUtil.updatedDataFailed();
		}

		return ResponseUtil.ok();
	}

	/**
	 * 账号手机号码重置
	 *
	 * @param body    请求内容 { password: xxx, mobile: xxx code: xxx }
	 *                其中code是手机验证码，目前还不支持手机短信验证码
	 * @param request 请求对象
	 * @return 登录结果 成功则 { errno: 0, errmsg: '成功' } 失败则 { errno: XXX, errmsg: XXX }
	 */
	@PostMapping("resetPhone")
	public Object resetPhone(@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		String password = JacksonUtil.parseString(body, "password");
		String mobile = JacksonUtil.parseString(body, "mobile");
		String code = JacksonUtil.parseString(body, "code");

		if (mobile == null || code == null || password == null) {
			return ResponseUtil.badArgument();
		}

		// 判断验证码是否正确
		String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
		if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code))
			return ResponseUtil.fail(AUTH_CAPTCHA_UNMATCH, "验证码错误");

		List<LitemallUser> userList = userService.queryByMobile(mobile);
		LitemallUser user = null;
		if (userList.size() > 1) {
			return ResponseUtil.fail(AUTH_MOBILE_REGISTERED, "手机号已注册");
		}
		user = userService.findById(userId);

		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		if (!encoder.matches(password, user.getPassword())) {
			return ResponseUtil.fail(AUTH_INVALID_ACCOUNT, "账号密码不对");
		}

		user.setMobile(mobile);
		if (userService.updateById(user) == 0) {
			return ResponseUtil.updatedDataFailed();
		}

		return ResponseUtil.ok();
	}

	/**
	 * 账号信息更新
	 *
	 * @param body    请求内容 { password: xxx, mobile: xxx code: xxx }
	 *                其中code是手机验证码，目前还不支持手机短信验证码
	 * @param request 请求对象
	 * @return 登录结果 成功则 { errno: 0, errmsg: '成功' } 失败则 { errno: XXX, errmsg: XXX }
	 */
	@PostMapping("profile")
	public Object profile(@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		String avatar = JacksonUtil.parseString(body, "avatar");
		Byte gender = JacksonUtil.parseByte(body, "gender");
		String nickname = JacksonUtil.parseString(body, "nickname");

		LitemallUser user = userService.findById(userId);
		if (!StringUtils.isEmpty(avatar)) {
			user.setAvatar(avatar);
		}
		if (gender != null) {
			user.setGender(gender);
		}
		if (!StringUtils.isEmpty(nickname)) {
			user.setNickname(nickname);
		}

		if (userService.updateById(user) == 0) {
			return ResponseUtil.updatedDataFailed();
		}

		return ResponseUtil.ok();
	}

	/**
	 * 微信手机号码绑定
	 *
	 * @param userId
	 * @param body
	 * @return
	 */
	@PostMapping("bindPhone")
	public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		LitemallUser user = userService.findById(userId);
		String encryptedData = JacksonUtil.parseString(body, "encryptedData");
		String iv = JacksonUtil.parseString(body, "iv");
		WxMaPhoneNumberInfo phoneNumberInfo = this.wxService.getUserService().getPhoneNoInfo(user.getSessionKey(),
				encryptedData, iv);
		String phone = phoneNumberInfo.getPhoneNumber();
		user.setMobile(phone);
		if (userService.updateById(user) == 0) {
			return ResponseUtil.updatedDataFailed();
		}
		return ResponseUtil.ok();
	}

	@PostMapping("logout")
	public Object logout(@LoginUser Integer userId) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		return ResponseUtil.ok();
	}

	@GetMapping("info")
	public Object info(@LoginUser Integer userId) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}

		LitemallUser user = userService.findById(userId);
		Map<Object, Object> data = new HashMap<Object, Object>();
		data.put("nickName", user.getNickname());
		data.put("avatar", user.getAvatar());
		data.put("gender", user.getGender());
		data.put("mobile", user.getMobile());

		return ResponseUtil.ok(data);
	}

	/**
	 * 商户认证
	 * 
	 * @param userId
	 * @param body
	 * @param request
	 * @return
	 */
	@PostMapping("applyAuth")
	public Object applyAuth(@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
    	Long count = wxQualificationsService.countByUserIdAndStatus(userId, (byte)0);
    	if(count>0) {
			return ResponseUtil.fail(AUTH_MERCHANT_CA_QUALIFICATION, "存在未审核的认证信息");
    	}
    	
		String contactName = JacksonUtil.parseString(body, "contactName");
		String contactTel = JacksonUtil.parseString(body, "contactTel");
		String contactAddress = JacksonUtil.parseString(body, "contactAddress");
		Byte userType = JacksonUtil.parseByte(body, "userType");

		if (StringUtils.isEmpty(contactName) || StringUtils.isEmpty(contactTel)
				|| StringUtils.isEmpty(contactAddress)) {
			return ResponseUtil.fail(AUTH_MERCHANT_CA_CONTACT, "联系人、电话、地址不能为空");
		}

		if (userType == null) {
			return ResponseUtil.badArgument();
		}

		// TODO 需要添加 联系电话格式校验及重复校验

		List<String> herbList = null;
		LitemallUserApprove userApprove = new LitemallUserApprove();
		userApprove.setContactName(contactName);
		userApprove.setContactTel(contactTel);
		userApprove.setContactAddress(contactAddress);
		userApprove.setUserType(userType);

		List<String> idCard1FileUrlList = JacksonUtil.parseStringList(body, "idCard1FileUrlList");
		if (CollectionUtils.isEmpty(idCard1FileUrlList)) {
			return ResponseUtil.fail(AUTH_MERCHANT_CA_QUALIFICATION, "请上传身份证正面");
		} else {
			userApprove.setIdCard1Url(String.join(",", idCard1FileUrlList));
		}
		List<String> idCard2FileUrlList = JacksonUtil.parseStringList(body, "idCard2FileUrlList");
		if (CollectionUtils.isEmpty(idCard2FileUrlList)) {
			return ResponseUtil.fail(AUTH_MERCHANT_CA_QUALIFICATION, "请上传身份证背面");
		} else {
			userApprove.setIdCard2Url(String.join(",", idCard2FileUrlList));
		}

		LitemallUser user = userService.findById(userId);
		if (user == null) {
			return ResponseUtil.fail(AUTH_MERCHANT_CA_USER, "获取用户信息异常，请刷新再试");
		}
		userApprove.setAdminId(user.getAdminId());

		// 资质信息设置初始值
		QualificationsVo qualificationsVo = wxQualificationsService.getQualificationsVo(userId);
		if (qualificationsVo != null) {
			userApprove.setShopId(qualificationsVo.getId());
			if (StringUtils.isEmpty(userApprove.getCompanyName())) {
				userApprove.setCompanyName(qualificationsVo.getCompanyName());
			}
			if (StringUtils.isEmpty(userApprove.getCompanyLogo())) {
				userApprove.setCompanyLogo(qualificationsVo.getCompanyLogo());
			}
		}

		if (DBConmonConstant.UserType.Personal.getValue() == userType) {
			herbList = JacksonUtil.parseStringList(body, "herbList");
			if (CollectionUtils.isEmpty(herbList)) {
				return ResponseUtil.fail(AUTH_MERCHANT_CA_HERB, "药品品类不能为空");
			}
			if (StringUtils.isEmpty(userApprove.getCompanyName())) {
				userApprove.setCompanyName(user.getNickname());
			}
			if (StringUtils.isEmpty(userApprove.getCompanyLogo())) {
				userApprove.setCompanyLogo(user.getAvatar());
			}

		} else if (DBConmonConstant.UserType.Manufactor.getValue() == userType
				|| DBConmonConstant.UserType.Distributor.getValue() == userType) {
			String companyName = JacksonUtil.parseString(body, "companyName");
			if (StringUtils.isEmpty(companyName)) {
				return ResponseUtil.fail(AUTH_MERCHANT_CA_COMPANY, "商户名称不能为空");
			}
			List<String> logoFileUrlList = JacksonUtil.parseStringList(body, "logoFileUrlList");
			if (CollectionUtils.isEmpty(logoFileUrlList)) {
				return ResponseUtil.fail(AUTH_MERCHANT_CA_QUALIFICATION, "请上传商户LOGO");
			} else {
				userApprove.setCompanyLogo(String.join(",", logoFileUrlList));
			}

//			String username = JacksonUtil.parseString(body, "username");
//			String password = JacksonUtil.parseString(body, "password");

//			if (StringUtils.isEmpty(username) || username.length() < 6) {
//				return ResponseUtil.fail(ADMIN_INVALID_NAME, "后端登录账号长度不能小于6");
//			}
//			if (StringUtils.isEmpty(password) || password.length() < 6) {
//				return ResponseUtil.fail(ADMIN_INVALID_PASSWORD, "后端登录密码长度不能小于6");
//			}

			List<String> certificatesFileUrlList = JacksonUtil.parseStringList(body, "certificatesFileUrlList");
			if (CollectionUtils.isEmpty(certificatesFileUrlList)) {
				return ResponseUtil.fail(AUTH_MERCHANT_CA_QUALIFICATION, "请上传营业执照");
			} else {
				userApprove.setCertificatesImage(String.join(",", certificatesFileUrlList));
			}

			/**
			 * TODO 安全隐患，最好允许不同商户可使用重复的后台管理账号，以防止知道账号的情况下暴力破解后端登录，解决方案，登录时用商户标识码、账号、密码一起登录
			 */
			// 检查既存的数据是否有重名的
//			long adminUsernameCount = userService.checkByAdminUsername(userId, username);
//			if (adminUsernameCount > 0) {
//				return ResponseUtil.fail(AUTH_NAME_REGISTERED, "后端登录账号已存在");
//			}
//			// 检查所有再申请的数据是否有重名的
//			adminUsernameCount = userApproveService.checkByAdminUsername(userId, username);
//			if (adminUsernameCount > 0) {
//				return ResponseUtil.fail(AUTH_NAME_REGISTERED, "后端登录账号已存在");
//			}

			userApprove.setCompanyName(companyName);
//			userApprove.setAdminUsername(username);
//			userApprove.setAdminPassword(password);

		}

		userApprove.setUserId(userId);
		userApprove.setApproveStatus((byte) 0);// TODO 待审核

		userApproveService.add(userApprove);
		if (CollectionUtils.isNotEmpty(herbList)) {
			List<LitemallUserHerbApproveItem> insertHerbList = Lists.newArrayList();
			LitemallUserHerbApproveItem herbItem = null;
			for (String herbGenericName : herbList) {
				herbItem = new LitemallUserHerbApproveItem();
				herbItem.setHerbGenericName(herbGenericName);
				herbItem.setUserApproveId(userApprove.getId());
				herbItem.setAddTime(LocalDateTime.now());
				herbItem.setUpdateTime(LocalDateTime.now());
				herbItem.setDeleted(false);

				insertHerbList.add(herbItem);
			}
			userHerbApproveItemService.addAll(insertHerbList);
		}

		Map<Object, Object> result = new HashMap<Object, Object>();
		return ResponseUtil.ok(result);
	}
}
